#pragma once
#ifndef __DECTIONARY_H__
#define __DECTIONARY_H__
#include <iostream>
#include <vector>
#include <map>
#include <set>

using std::string;
using std::vector;
using std::map;
using std::pair;
using std::set;
using std::cout;
using std::endl;

struct CandidateResult{
    string _word;   //单词(词语)
    int _freq;      //单词出现的频次
    int _dist;      //与要查询关键字的距离
    
//对CandidateResult的<运算符进行重载，便于比较两个结果的热度
    friend bool operator<(const CandidateResult& lhs,const CandidateResult& rhs);
};


class Dictionary
{
public:
    Dictionary(const string& dictPathname = "../data/dict.dat",
               const string& indexPathname = "../data/dictIndex.dat")
        :_dictPathname(dictPathname)
        ,_indexPathname(indexPathname)
        {
            //读取磁盘中的字典和索引信息
            readInfo();
            //读取磁盘中的字典和索引信息
            //为容器预先分配一些内存,防止频繁扩容
            _dict.reserve(1000);
        }
private:
    //读取磁盘中的字典和索引信息
    void readInfo();
    //根据要查询的单词(词语),返回包括该单词某一个字母的单词(汉字)的并集
    void getQuerySet(const string& word,set<int>& unionSet);
    //计算两个单词的最小编辑距离
    int editDistance(const string& lhs,const string& rhs);
    //根据得到的并集,构建CandidateResult集合
    void getCandidateResult(const string& word,set<int> unionSet,vector<CandidateResult>& ResultList);
public:
    //获得关键字未排序的查询结果
    void doQuery(const string& word,vector<CandidateResult>& ResultList);
private:
    string _dictPathname;
    string _indexPathname;

    vector<pair<string,int>> _dict;
    map<string,set<int>> _index;

};

#endif
